﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using XLua;

/// <summary>
/// Xlua管理器
/// </summary>
public class XLuaManager : Singleton<XLuaManager> {

    public LuaEnv luaEnv = null;

    // Use this for initialization
    public void Start () {
        luaEnv = new LuaEnv();
        if (luaEnv != null)
        {
            /******************读取res的lua******************/
            //luaEnv.AddLoader(CustomLoader);
            //LoadMain();

            /******************读取ab的lua******************/
            AddSearchPath();
            AddLuaLoader();
            RequireLua("Main");
        }
    }

    // Update is called once per frame
    private void Update()
    {
        if (luaEnv != null)
        {
            luaEnv.Tick();

            if (Time.frameCount % 100 == 0)
            {
                luaEnv.FullGc();
            }
        }
    }

    public void Dispose()
    {
        if (luaEnv != null)
        {
            luaEnv.Dispose();
            luaEnv = null;
        }
    }

    /*********************************从res路径加载***********************************/
    void LoadMain()
    {
        try
        {
            if (luaEnv != null)
            {
                luaEnv.DoString("require('Main')");
            }
        }
        catch (System.Exception ex)
        {
            string msg = string.Format("xLua exception : {0}\n {1}", ex.Message, ex.StackTrace);
            Debug.LogError(msg, null);
        }
    }
    public static byte[] CustomLoader(ref string filepath)
    {
        Debug.Log("Load xLua script : " + filepath);
        // TODO：此处从项目资源管理器加载lua脚本
        TextAsset textAsset = (TextAsset)Resources.Load("xlua/" + filepath.Replace(".", "/") + ".lua");
        //TextAsset textAsset = (TextAsset)ResourceMgr.instance.SyncLoad(ResourceMgr.RESTYPE.XLUA_SCRIPT, filepath).resObject;
        if (textAsset != null)
        {
            return textAsset.bytes;
        }
        return null;
    }


    /********************************从ab路径中加载lua(pc版本可改代码)*******************************/
    public void AddSearchPath()
    {
        string fullPath = AppConst.luaDir;
        if (!Path.IsPathRooted(fullPath))
        {
            throw new LuaException(fullPath + " is not a full path");
        }


        fullPath = ToPackagePath(fullPath);
        LuaFileUtils.Instance.AddSearchPath(fullPath);
    }
    string ToPackagePath(string path)
    {
        //StringBuilder sb = StringBuilderCache.Acquire();
        StringBuilder sb = new StringBuilder();
        sb.Append(path);
        sb.Replace('\\', '/');

        if (sb.Length > 0 && sb[sb.Length - 1] != '/')
        {
            sb.Append('/');
        }

        sb.Append("?.lua");

        var ToPackagePath = sb.ToString();
        UnityEngine.Debug.Log(" ToPackagePath  " + ToPackagePath);
        //return StringBuilderCache.GetStringAndRelease(sb);
        return ToPackagePath;
    }
    void AddLuaLoader()
    {
        luaEnv.AddLoader(LuaFileUtils.Instance.ReadFile);
    }

    /******************************通用*******************************/
    public void RequireLua(string luaName)
    {
        luaEnv.DoString("require '"+ luaName +"'");
    }
    //无参的lua
    public void StartLua(string func)
    {
        Action main = luaEnv.Global.Get<Action>(func);
        main();
    }
    [CSharpCallLua]
    public delegate int FDelegate(string name, object data);
    //函数名，分支名，数据
    public void StartLua(string func, string name, object data)
    {
        FDelegate main = luaEnv.Global.Get<FDelegate>(func);
        main(name,data);
    }
}
